package com.pomr.service.equipmentreceive.impl;

import java.text.SimpleDateFormat;
import java.util.*;

import com.pomr.entity.EquipmentApc;
import com.pomr.entity.ReceiveEntity;
import com.pomr.entity.ReceiveParam;
import com.pomr.entity.ReceiverUser;
import com.pomr.model.equipmentstorage.*;
import com.pomr.model.menu.EquipmentKind;
import com.pomr.model.sys.Agency;
import com.pomr.model.sys.FaultTreatment;
import com.pomr.model.sys.MsgContent;
import com.pomr.util.common.IdcardUtils;
import com.pomr.util.common.ResponseData;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.pomr.dao.equipmentreceive.ReceiveDao;
import com.pomr.model.health.Legend;
import com.pomr.model.health.Option;
import com.pomr.model.health.PersonRecord;
import com.pomr.model.simstorage.SimStorageDetail;
import com.pomr.model.sys.User;
import com.pomr.service.equipmentreceive.ReceiveService;
import com.pomr.util.page.Page;
@Service
public class ReceiveServiceImpl implements ReceiveService {
	@Autowired
	@Qualifier("receiveDaoImpl")
	private ReceiveDao receiveDao;

	@Override
	public Page<List<EquipmentStorage>> searchEquipByPerson(String idcard, String page, String limit) throws Exception {
		StringBuilder sb = new StringBuilder();
		sb.append("from EquipmentLeader el where 1=1 ");
		sb.append("and el.record.idcard = '"+idcard+"'");
		sb.append(" order by el.createTime desc");
		String hqlStr = sb.toString();

		String queryhql = "select distinct el.receive.match.equipmentdetail.equipmentStorage " + hqlStr;
		String counthql = "select count(1) from EquipmentStorage where id in (select distinct el.receive.match.equipmentdetail.equipmentStorage.id "+hqlStr+")";
		Page<List<EquipmentStorage>> p = new Page<List<EquipmentStorage>>();
		p.setCunrrentPage(Integer.valueOf(page));
		p.setPageSize(Integer.valueOf(limit));

		return receiveDao.showPage(queryhql, counthql, p);
	}

	@Override
	public List<PersonRecord> searchRecords(String rs,User user) throws Exception {
		StringBuilder sb = new StringBuilder();
		sb.append("from PersonRecord where (status!='1' or status=null) ");
		if(rs != null && !"".equals(rs)){
			sb.append(" and (name like '%"+rs+"%' or idcard = '"+rs+"')");
		}
		sb.append(" and agency.id = "+user.getAgency().getId());
		return receiveDao.findByHql(sb.toString());
	}

	@Override
	public List<EquipmentStorageDetail> searchEquipments(User user) throws Exception {
		StringBuilder sb = new StringBuilder();
		sb.append("from EquipmentStorageDetail where equipmentStorage.agency.id = "+user.getAgency().getId());
		sb.append(" and equipmentStatus.id != 2 and equipmentCon.id != 2 and equipmentCon.id != 3 and equipmentStatus.id != 3");
		return receiveDao.findByHql(sb.toString());
	}
	
	@Override
	public List<EquipmentStorageDetail> searchEquipmentsUsed(User user) throws Exception {
		StringBuilder sb = new StringBuilder();
		sb.append("from EquipmentStorageDetail where equipmentStorage.agency.id = "+user.getAgency().getId());
		sb.append(" and equipmentStatus.id = 2");
		return receiveDao.findByHql(sb.toString());
	}

	@Override
	public List<SimStorageDetail> searchSims(User user) throws Exception {
		StringBuilder sb = new StringBuilder();
		sb.append("from SimStorageDetail where simStorage.agency.id = "+user.getAgency().getId());
		sb.append(" and equipmentStatus.id != 2 and equipmentStatus.id != 3 and equipmentCon.id != 2 and equipmentCon.id != 3");
		return receiveDao.findByHql(sb.toString());
	}

	
	@Override
	@Transactional(rollbackFor=Exception.class)
	public int addReceive(User user, ReceiveEntity receiveEnt) throws Exception {
		Receive receive = receiveEnt.getReceive();
		receive.setCreateUser(user);
		receive.setCreateTime(new Date());
		if(receive.getReceipts()!=null && receive.getReceipts().size()>0){
			for(ReceiveRecipt receipt : receive.getReceipts()){
				receipt.setCreateTime(new Date());
				receipt.setReceiptUser(user);
			}
		}
		//查看用户是否已经领用过同种设备
		String ishas = "from Receive where record.id="+receiveEnt.getReceive().getRecord().getId()+" and receiveTime=null and " +
				"match.equipmentdetail.equipmentStorage.equipment.kind.id=" +
				"(select dm.equipmentStorage.equipment.kind.id from EquipmentStorageDetail dm where dm.id="+receive.getMatch().getEquipmentdetail().getId()+")";
		List rs = receiveDao.findByHql(ishas);
		if(rs!=null && !rs.isEmpty()){
			throw new Exception("用户已经领取了该类型的设备，请退还后在申请");
		}
		//如果sim卡信息未上传 查询设备是否已经被领取
		if(receive.getMatch().getSimdetail()==null || receive.getMatch().getSimdetail().getId()==null){
			if(receive.getMatch().getEquipmentdetail()!=null && receive.getMatch().getEquipmentdetail().getId()!=null){
				String ishql = "from DeviceMatch where equipmentdetail.id="+receive.getMatch().getEquipmentdetail().getId()+" and noBindTime=null";
				List<DeviceMatch> ms = receiveDao.findByHql(ishql);
				if(ms==null || ms.size()<=0){
					throw new Exception("信息不完整,sim卡信息缺失");
				}else{
					receive.setMatch(ms.get(0));
				}
			}else{
				throw new Exception("信息不完整,设备信息缺失");
			}
			
		}
		
		//查看设备、SIM卡是否已被使用
		String issb = "from Receive where (match.equipmentdetail.id="+receive.getMatch().getEquipmentdetail().getId()+" "
				+ "or match.simdetail.id="+receive.getMatch().getSimdetail().getId()+") "
				+ "and (receiveTime = null or receiveTime = '')";
		List<Object> rec = receiveDao.findByHql(issb);
		if(rec!=null && rec.size()>0){
			throw new Exception("设备或者SIM卡已被使用");
		}

		//保存设备与sim卡信息绑定
		DeviceMatch match = receive.getMatch();
		match.setBindTime(new Date());
		match.setUser(user);
		//查看设备是否已经与SIM卡绑定
		String es = "from DeviceMatch where (equipmentdetail.id="+receive.getMatch().getEquipmentdetail().getId()+" "
				+ "or simdetail.id="+receive.getMatch().getSimdetail().getId()+") "
				+" and noBindTime=null";
		List<DeviceMatch> matchs = receiveDao.findByHql(es);
		int idkey = 0;
		if(matchs==null || matchs.size()<=0){//没有绑定
			if((idkey = receiveDao.addNumKey(match))<=0){
				throw new Exception("保存绑定信息失败");
			}
		}else if(matchs.size()==1){//设备与sim卡绑定
			idkey = matchs.get(0).getId();
		}else{
			throw new Exception("设备与SIM卡已经绑定不同的设备");
		}
		match.setId(idkey);
		receive.setMatch(match);
		EquipmentStorageDetail edetail = receiveDao.getById(EquipmentStorageDetail.class, receive.getMatch().getEquipmentdetail().getId());
		receive.setEquipmentName(edetail.getEquipmentName());
		receive.setEmanufacturerName(edetail.getManufacturerName());
		receive.setEsN(edetail.getsN());
		receive.setEspecification(edetail.getEspecification());
		SimStorageDetail sdetail = receiveDao.getById(SimStorageDetail.class, receive.getMatch().getSimdetail().getId());
		receive.setSmanufacturerName(sdetail.getManufacturerName());
		receive.setNetworkName(sdetail.getNerworkName());
		receive.setSsN(sdetail.getsN());
		int rid = 0;
		//保存领用记录
		if((rid = receiveDao.addNumKey(receive))>0){
			/**********保存设备-用户绑定记录开始********************/
			Map<String,PersonRecord> records = receiveEnt.getRecords();
			if(records!=null && records.size()>0){
				receive.setId(rid);
				for(Map.Entry<String, PersonRecord> record : records.entrySet()){
					EquipmentLeader leader = new EquipmentLeader();
					leader.setCreateTime(new Date());
					leader.setCreateUser(user);
					leader.setReceive(receive);
					leader.setRecord(record.getValue());
					leader.setUserNo(record.getKey());//设置用户编号1...n
					if(!receiveDao.add(leader)){
						throw new Exception("绑定设备用户失败");
					}
				}
			}else{
				//默认领用人为第一绑定人
				EquipmentLeader leader = new EquipmentLeader();
				leader.setCreateTime(new Date());
				leader.setCreateUser(user);
				receive.setId(rid);
				leader.setReceive(receive);
				leader.setRecord(receive.getRecord());
				if(!receiveDao.add(leader)){
					throw new Exception("绑定设备用户失败");
				}
			}
			/**********保存设备-用户绑定记录结束********************/

			// 更改库存信息状态
			String hql = "update EquipmentStorageDetail set equipmentStatus.id=2 where id="+receive.getMatch().getEquipmentdetail().getId();
			if(!receiveDao.editHql(hql)){
				throw new Exception("更新设备使用状态失败");
			}
			//更新设备库存数
			hql = "update EquipmentStorage set stockNumber = stockNumber-1 where id = ("
					+ "select equipmentStorage.id from EquipmentStorageDetail where id="+receive.getMatch().getEquipmentdetail().getId()+")";
			if(!receiveDao.editHql(hql)){
				throw new Exception("更新设备库存失败");
			}
			
			String simhql = "update SimStorageDetail set equipmentStatus.id=2 where id="+receive.getMatch().getSimdetail().getId();
			if(!receiveDao.editHql(simhql)){
				throw new Exception("更新SIM卡使用状态失败");
			}
			//更新SIM卡库存数
			simhql = "update SimStorage set stockNumber = stockNumber-1 where id = ("
					+ "select simStorage.id from SimStorageDetail where id="+receive.getMatch().getSimdetail().getId()+")";
			if(!receiveDao.editHql(simhql)){
				throw new Exception("更新SIM卡库存失败");
			}
			
		}else{
			throw new Exception("保存领用信息失败");
		}
		
		return rid;
	}
	
	public ReceiveRecipt searchReceipt(int id) throws Exception{
		String sel = "from ReceiveRecipt rr where rr.receice.id = "+id+" and rr.money>=0 order by rr.createTime";
		ReceiveRecipt receipt = (ReceiveRecipt) (receiveDao.findByHqlNoCache(sel).get(0));
		sel = "from Receive where id = "+id;
		Receive re = (Receive) receiveDao.findByHqlNoCache(sel).get(0);
		receipt.setReceice(re);
		return receipt;
	}

	@Override
	public Page<List<Receive>> searchReceives(String re, String eqid, String page, String limit, User user) throws Exception {
		StringBuilder sb = new StringBuilder();
		sb.append("from Receive where 1=1 ");
		sb.append(" and createUser.agency.id=(select distinct agency.id from User where id="+user.getId()+")");
		if(re != null && !"".equals(re)){
			sb.append("and record.id in (select pr.id from PersonRecord pr where pr.idcard = '"+re+"' or pr.name = '"+re+"') ");
		}
		if(eqid!=null && !eqid.equals("")){
			sb.append("and match.equipmentdetail.id="+eqid);
		}
		sb.append(" order by createTime desc");
		String hqlStr = sb.toString();
		Page<List<Receive>> p = new Page<List<Receive>>();
		p.setCunrrentPage(Integer.valueOf(page));
		p.setPageSize(Integer.valueOf(limit));
		
		return receiveDao.showPage(hqlStr, "select count(1) "+hqlStr, p);
	}

	
	@Override
	public Receive searchReceiveById(Receive receive) throws Exception {
		String hql = "from Receive r left join fetch r.equipment left join fetch r.sim left join fetch r.record "
				+ "left join fetch r.createUser where r.id="+receive.getId()+" and r.receiveTime = null";
		List<Receive> receives = receiveDao.findByHqlNoCache(hql);
		if(receives==null || receives.size()<=0){
			return null;
		}
		return receives.get(0);
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public boolean backReceiveById(String id, String isjb, User user) throws Exception {
//		Receive breceive = receiveDao.getById(Receive.class, receive.getId());
		String qhl = "from Receive r left join fetch r.match where r.id="+id;
		List<Receive> rs = receiveDao.findByHql(qhl);
		if(rs == null || rs.size()<=0){
			return false;
		}
		Receive breceive = rs.get(0);
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		String sql = "update Receive set receiveTime = ? where id = "+breceive.getId();
		if(receiveDao.editHql(sql,new Object[]{new Date()})){
			//更新归还时间后  添加定金返还收据   修改库存状态(使用状态更为空闲状态、损坏状态不变)
			//获取定金信息
			String hql ="from ReceiveRecipt where receice.id = "+breceive.getId()+" and money >=0 ";
			List<ReceiveRecipt> receipts = receiveDao.findByHql(hql);
			if(receipts!=null && receipts.size()>0){
				Receive re = new Receive();
				ReceiveRecipt receipt = receipts.get(0);
				ReceiveRecipt r = new ReceiveRecipt();
				r.setCreateTime(new Date());
				r.setReceiptUser(user);
				r.setMoney(0-receipt.getMoney());
				re.setId(breceive.getId());
				r.setReceice(re);
				if(!receiveDao.add(r)){
					throw new Exception("添加退还定金收据信息");
				}
			}else{
		//		throw new Exception("未找到定金收据信息");
			}
			//更新解除绑定用户
			hql = "update EquipmentLeader set nouseTime='"+sf.format(new Date())+"' where receive.id="+breceive.getId()+" and nouseTime=null";
			if(!receiveDao.editHql(hql)){
				throw new Exception("解绑用户失败");
			}
			//更新设备信息
			hql = "update EquipmentStorageDetail set equipmentStatus.id="+isjb+" where id = (select match.equipmentdetail.id from Receive where id="+id+")";
			if(!receiveDao.editHql(hql)){
				throw new Exception("更新设备状态失败");
			}
			//更新设备库存数
			hql = "update EquipmentStorage set stockNumber = stockNumber+1 where id = ("
					+ "select match.equipmentdetail.equipmentStorage.id from Receive where id="+id+")";
			if(!receiveDao.editHql(hql)){
				throw new Exception("更新设备库存失败");
			}
			//更新sim卡信息
			
			hql = "update SimStorageDetail set equipmentStatus.id="+isjb+" where id = (select match.simdetail.id from Receive where id="+id+")";
			if(!receiveDao.editHql(hql)){
				throw new Exception("更新SIM卡状态失败");
			}
			//更新SIM卡库存数
			hql = "update SimStorage set stockNumber = stockNumber+1 where id = ("
					+ "select match.simdetail.simStorage.id from Receive where id="+id+")";
			if(!receiveDao.editHql(hql)){
				throw new Exception("更新SIM卡库存失败");
			}
			if(isjb.equals("1")){//解绑
				hql = "from DeviceMatch where id=(select match.id from Receive where id="+id+")";
				DeviceMatch dm = (DeviceMatch) receiveDao.findByHql(hql).get(0);
				dm.setNoBindTime(new Date());
				if(!receiveDao.editEntity(dm)){
					throw new Exception("设备解绑操作失败");
				}
			}
		}else{
			return false;
		}
		return true;
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public boolean editReceiveById(Receive receive) throws Exception {
//		String hql = "update EquipmentStorageDetail set equipmentCon.id = "+receive.getEquipment().getEquipmentCon().getId()
//				+",remark='"+receive.getEquipment().getRemark()+"' where id = "+receive.getEquipment().getId();
//		receiveDao.editHql(hql);//更新设备信息
//		hql = "update SimStorageDetail set equipmentCon.id = "+receive.getSim().getEquipmentCon().getId()
//				+",remark='"+receive.getSim().getRemark()+"' where id = "+receive.getSim().getId();
//		receiveDao.editHql(hql);//更新sim卡信息
//		
		return true;
	}

	@Override
	public double searchMonry(String sbid, String simid) throws Exception {
		String sql = "select sum(de.earnestmoney) from ("
				+ "select earnestmoney from equipment_storage where id = (select storage_id from equipment_storage_detail where id = "+sbid+") union "
				+ "select earnestmoney from sim_storage where id = (select storage_id from sim_storage_detail where id = "+simid+")"
				+ ") de";
		return receiveDao.searchMonry(sql);
	}

	@Override
	public List<PersonRecord> searchRecords(String cond) throws Exception {
		String hql = "from PersonRecord where (name like '%"+cond+"%' or idcard='"+cond+"')";
		return receiveDao.findByHql(hql);
	}

	@Override
	public List<EquipmentStorage> searchReceives(String id) throws Exception {
//		String hql = "from Receive where record.id="+id+" order by createTime desc";
		String hql = "from EquipmentStorage where id in ("
				+ "select receive.match.equipmentdetail.equipmentStorage.id from EquipmentLeader where record.id="+id
				+ ")";
		return receiveDao.findByHql(hql);
	}

	@Override
	public Option searchMonitors(String id,String pid,String time1,String time2) throws Exception {
		String hql = "from MonitoringData where leader.receive.match.equipmentdetail.equipmentStorage.id = "+id+" and leader.record.id="+pid+" ";
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Calendar calendar = Calendar.getInstance();
		Date date1 = null;
		Date date2 = null;
		if(time2 == null || time2.trim().equals("")){
			date2 = new Date(System.currentTimeMillis());
			if(time1 == null || time1.trim().equals("")){
		        calendar.setTime(date2);
		        calendar.add(Calendar.MONTH, -3);
		        date1 = calendar.getTime();
			}else{
				date1 = sdf.parse(time1);
			}
			calendar.setTime(date2);
	        calendar.add(Calendar.DAY_OF_YEAR, 1);
	        date2 = calendar.getTime();
		}else{
			date2 = sdf.parse(time2);
			if(time1 != null && !time1.trim().equals("")){
				date1 = sdf.parse(time1);
			}else{
				calendar.setTime(date2);
		        calendar.add(Calendar.MONTH, -3);
		        date1 = calendar.getTime();
			}
			calendar.setTime(date2);
	        calendar.add(Calendar.DAY_OF_YEAR, 1);
	        date2 = calendar.getTime();
		}
		hql += " and monitorTime>=:starttime and monitorTime<:endtime order by monitorTime";
		Map<String, Date> dmap = new HashMap<String, Date>();
		dmap.put("starttime", date1);
		dmap.put("endtime", date2);
		System.out.println(sdf.format(date1));
		System.out.println(sdf.format(date2));
		List<MonitoringData> monitors = receiveDao.findByHqlWithDate(hql,dmap,-1);
		if(monitors!=null && monitors.size()>0){
			List<String> legend = new LinkedList<String>();//数据分类
			List<Date> xAxis = new LinkedList<Date>();//X轴坐标
			Map<String,Legend> yAxis = new HashMap<String, Legend>();//y轴坐标
			MonitoringData md = monitors.get(0);
			Receive receive = md.getLeader().getReceive();
			Option opt = new Option();
			opt.setTitle(receive.getEquipmentName()+"检测数据");//标题
			opt.setSubtext(md.getLeader().getRecord().getName()+"  "+md.getLeader().getRecord().getIdcard());//副标题
			
			Document document = null;
			Element rootElt = null;
			SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
			for(int i=0; i<monitors.size(); i++){
				if(xAxis.contains(monitors.get(i).getMonitorTime())){
					continue;
				}
				System.out.println(monitors.get(i).getMonitorTime());
				xAxis.add(monitors.get(i).getMonitorTime());
				System.out.println("数据："+monitors.get(i).getData());
				document = DocumentHelper.parseText(monitors.get(i).getData());
				rootElt = document.getRootElement(); // 获取根节点
				Element letitleElt = rootElt.element("legendtitle");
				String letitles = letitleElt.getData().toString();
				String[] lts = letitles.split(",");
				for(String s:lts){
					if(legend.contains(s)){
						continue;
					}
					legend.add(s.trim());
				}
				
				
				rootElt = rootElt.element("legends");
				Iterator iter = rootElt.elementIterator("legend"); // 获取根节点下的子节点legend
				
				while(iter.hasNext()){
					Element itRlt = (Element) iter.next();
					Element titleElt = itRlt.element("title");
					if(titleElt!=null){
						String title = titleElt.getData().toString().trim();
						if(legend.contains(title)){
							Legend lgd = null;
							if(yAxis.containsKey(title)){
								lgd = yAxis.get(title);
								List<Double> yax = lgd.getyAxis();
								Element d = itRlt.element("data");
								if(d!=null){
									String data = d.getData().toString().trim();
									if(data!=null && !data.equals("")){
										yax.add(Double.valueOf(data));
									}else{
										yax.add(null);
									}
								}else{
									yax.add(null);
								}
								
								d = itRlt.element("aver");
								Boolean avr = lgd.getIsAver();
								if(avr != null){
									if(d == null){
										String avrstr = d.getData().toString().trim();
										if(avrstr!=null && avrstr.equals("true")){
											avr = true;
										}else{
											avr = false;
										}
									}else{
										avr = false;
									}
								}
								
							}else{
								lgd = new Legend();
								lgd.setTitle(title);//数据分类
								List<Double> datas = new ArrayList<Double>();
								Element d = itRlt.element("data");
								if(d!=null){
									String data = d.getData().toString().trim();
									if(data!=null && !data.equals("")){
										datas.add(Double.valueOf(data));
									}else{
										datas.add(null);
									}
								}else{
									datas.add(null);
								}
								lgd.setyAxis(datas);//添加数据
								d = itRlt.element("aver");
								Boolean avr = false;
								if(d!=null){
									String avrstr = d.getData().toString().trim();
									if(avrstr!=null && avrstr.equals("true")){
										avr = true;
									}
								}
								lgd.setIsAver(avr);//设置平均值显示
							}
							yAxis.put(title, lgd);
						}
					}
				}
			}
			opt.setxAxis(xAxis);
			opt.setyAxis(yAxis);
			opt.setLegend(legend);
			return opt;
		}
		return null;
	}

	@Override
	public List<EquipmentStorage> searchReceivesByCon(String con) throws Exception {
		
		String hql = "from EquipmentStorage where id in ("
				+ "select match.equipmentdetail.equipmentStorage.id from Receive where record.idcard='"+con+"'"
				+ ")"; 
//		String hql = "from Receive r where r.record.id=(select id from PersonRecord where idcard='"+con+"') group by  r.equipment.equipment.id,r.equipment.manufacturer.id  order by r.createTime desc";
		
		return receiveDao.findByHql(hql);
//		return stroages;
	}

	@Override
	public SimStorageDetail seachBindSim(String eid) throws Exception {
		String hql = "from SimStorageDetail where id = (select simdetail.id from DeviceMatch where equipmentdetail.id="+eid+" and noBindTime=null)";
		List<SimStorageDetail> details = receiveDao.findByHql(hql);
		if(details!=null && details.size()>0){
			return details.get(0);
		}
		return null;
	}

	@Override
	public EquipmentStorageDetail seachBindEquip(String eid) throws Exception {
		String hql = "from EquipmentStorageDetail where id = (select equipmentdetail.id from DeviceMatch where simdetail.id="+eid+" and noBindTime=null)";
		List<EquipmentStorageDetail> details = receiveDao.findByHql(hql);
		if(details!=null && details.size()>0){
			return details.get(0);
		}
		return null;
	}

	@Override
	public Map<String, Object> searchBind(String type, User user) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		if(type.equals("0")){//未绑定的设备
			StringBuilder sb = new StringBuilder();
			sb.append("from EquipmentStorageDetail where equipmentStorage.agency.id = "+user.getAgency().getId());
			sb.append(" and equipmentStatus.id != 2 and equipmentCon.id != 2 and equipmentCon.id != 3 and equipmentStatus.id != 3");
			List<EquipmentStorageDetail> equipments = receiveDao.findByHql(sb.toString());
			map.put("equipments", equipments);
			sb = new StringBuilder();
			sb.append("from SimStorageDetail where simStorage.agency.id = "+user.getAgency().getId());
			sb.append(" and equipmentStatus.id != 2 and equipmentStatus.id != 3 and equipmentCon.id != 2 and equipmentCon.id != 3");
			List<SimStorageDetail> sims = receiveDao.findByHql(sb.toString());
			map.put("sims", sims);
		}else{
			StringBuilder sb = new StringBuilder();
			sb.append("from EquipmentStorageDetail where equipmentStorage.agency.id = "+user.getAgency().getId());
			sb.append(" and equipmentStatus.id != 2 and equipmentCon.id != 2 and equipmentCon.id != 3 and equipmentStatus.id = 3");
			List<EquipmentStorageDetail> equipments = receiveDao.findByHql(sb.toString());
			map.put("equipments", equipments);
			sb = new StringBuilder();
			sb.append("from SimStorageDetail where simStorage.agency.id = "+user.getAgency().getId());
			sb.append(" and equipmentStatus.id != 2 and equipmentStatus.id = 3 and equipmentCon.id != 2 and equipmentCon.id != 3");
			List<SimStorageDetail> sims = receiveDao.findByHql(sb.toString());
			map.put("sims", sims);
		}
		return map;
	}

	@Override
	public SimStorageDetail searchSimByEqui(String eid) throws Exception {
		String hql = "select dm.simdetail from DeviceMatch dm where dm.equipmentdetail.id="+eid;
		List<SimStorageDetail> sims = receiveDao.findByHql(hql);
		if(sims!=null && sims.size()>0){
			return sims.get(0);
		}
		return null;
	}

	@Override
	public Page<List<PersonRecord>> searchReceivePersons(String idcard, String page, String limit, User user) throws Exception {
		String hql = "from EquipmentLeader el where el.receive.createUser.agency.id=(" +
				"select u.agency.id from User u where u.id="+user.getId()+")";
		if(idcard !=null && !idcard.equals("")){
			hql += " and el.record.idcard = '"+idcard+"'";
		}
		String queryhql = "select distinct el.record "+hql;
		String counthql = "from PersonRecord where id in (select distinct el.record.id "+hql+")";

		Page<List<PersonRecord>> p = new Page<List<PersonRecord>>();
		p.setCunrrentPage(Integer.valueOf(page));
		p.setPageSize(Integer.valueOf(limit));
		return receiveDao.showPage(queryhql, "select count(1) "+counthql, p);
	}

	@Override
	public Option searchMonitorsByEquip(String eid, String idcard, String time1,String time2) throws Exception {
		String hql = "from EquipmentStorage where id="+eid;
		List<EquipmentStorage> es = receiveDao.findByHql(hql);
		if(es!=null && es.size()>0){
			EquipmentStorage e = es.get(0);
			String mhql = "from MonitoringData where leader.receive.match.equipmentdetail.equipmentStorage.id = "+eid+" and leader.record.idcard='"+idcard+"' ";
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			Calendar calendar = Calendar.getInstance();
			Date date1 = null;
			Date date2 = null;
			if(time2 == null || time2.trim().equals("")){
				date2 = new Date(System.currentTimeMillis());
				if(time1 == null || time1.trim().equals("")){
					calendar.setTime(date2);
					calendar.add(Calendar.MONTH, -3);
					date1 = calendar.getTime();
				}else{
					date1 = sdf.parse(time1);
				}
				calendar.setTime(date2);
				calendar.add(Calendar.DAY_OF_YEAR, 1);
				date2 = calendar.getTime();
			}else{
				date2 = sdf.parse(time2);
				if(time1 != null && !time1.trim().equals("")){
					date1 = sdf.parse(time1);
				}else{
					calendar.setTime(date2);
					calendar.add(Calendar.MONTH, -3);
					date1 = calendar.getTime();
				}
				calendar.setTime(date2);
				calendar.add(Calendar.DAY_OF_YEAR, 1);
				date2 = calendar.getTime();
			}
			mhql += " and monitorTime>=:starttime and monitorTime<:endtime order by monitorTime";
			Map<String, Date> dmap = new HashMap<String, Date>();
			dmap.put("starttime", date1);
			dmap.put("endtime", date2);
			List<MonitoringData> monitors = receiveDao.findByHqlWithDate(mhql,dmap,-1);
			if(monitors!=null && monitors.size()>0){
				List<String> legend = new LinkedList<String>();//数据分类
				List<Date> xAxis = new LinkedList<Date>();//X轴坐标
				Map<String,Legend> yAxis = new HashMap<String, Legend>();//y轴坐标
				MonitoringData md = monitors.get(0);
				Receive receive = md.getLeader().getReceive();
				Option opt = new Option();
				opt.setTitle(receive.getEquipmentName()+"检测数据");//标题
				opt.setSubtext(md.getLeader().getRecord().getName()+"  "+md.getLeader().getRecord().getIdcard());//副标题

				Document document = null;
				Element rootElt = null;
				SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
				for(int i=0; i<monitors.size(); i++){
					if(xAxis.contains(monitors.get(i).getMonitorTime())){
						continue;
					}
					System.out.println(monitors.get(i).getMonitorTime());
					xAxis.add(monitors.get(i).getMonitorTime());
					System.out.println("数据："+monitors.get(i).getData());
					document = DocumentHelper.parseText(monitors.get(i).getData());
					rootElt = document.getRootElement(); // 获取根节点
					Element letitleElt = rootElt.element("legendtitle");
					String letitles = letitleElt.getData().toString();
					String[] lts = letitles.split(",");
					for(String s:lts){
						if(legend.contains(s)){
							continue;
						}
						legend.add(s.trim());
					}


					rootElt = rootElt.element("legends");
					Iterator iter = rootElt.elementIterator("legend"); // 获取根节点下的子节点legend

					while(iter.hasNext()){
						Element itRlt = (Element) iter.next();
						Element titleElt = itRlt.element("title");
						if(titleElt!=null){
							String title = titleElt.getData().toString().trim();
							if(legend.contains(title)){
								Legend lgd = null;
								if(yAxis.containsKey(title)){
									lgd = yAxis.get(title);
									List<Double> yax = lgd.getyAxis();
									Element d = itRlt.element("data");
									if(d!=null){
										String data = d.getData().toString().trim();
										if(data!=null && !data.equals("")){
											yax.add(Double.valueOf(data));
										}else{
											yax.add(null);
										}
									}else{
										yax.add(null);
									}

									d = itRlt.element("aver");
									Boolean avr = lgd.getIsAver();
									if(avr != null){
										if(d == null){
											String avrstr = d.getData().toString().trim();
											if(avrstr!=null && avrstr.equals("true")){
												avr = true;
											}else{
												avr = false;
											}
										}else{
											avr = false;
										}
									}

								}else{
									lgd = new Legend();
									lgd.setTitle(title);//数据分类
									List<Double> datas = new ArrayList<Double>();
									Element d = itRlt.element("data");
									if(d!=null){
										String data = d.getData().toString().trim();
										if(data!=null && !data.equals("")){
											datas.add(Double.valueOf(data));
										}else{
											datas.add(null);
										}
									}else{
										datas.add(null);
									}
									lgd.setyAxis(datas);//添加数据
									d = itRlt.element("aver");
									Boolean avr = false;
									if(d!=null){
										String avrstr = d.getData().toString().trim();
										if(avrstr!=null && avrstr.equals("true")){
											avr = true;
										}
									}
									lgd.setIsAver(avr);//设置平均值显示
								}
								yAxis.put(title, lgd);
							}
						}
					}
				}
				opt.setxAxis(xAxis);
				opt.setyAxis(yAxis);
				opt.setLegend(legend);
				return opt;
			}else{
				return null;
			}
		}else{
			return null;
		}
	}

	@Override
	public Page<List<EquipmentStorage>> searchEquipOfAgency(String page, String limit, User user) throws Exception {
		String hql = "from EquipmentStorage where agency.id=(select agency.id from User where id="+user.getId()+")";
		Page<List<EquipmentStorage>> p = new Page<List<EquipmentStorage>>();
		p.setCunrrentPage(Integer.valueOf(page));
		p.setPageSize(Integer.valueOf(limit));
		return receiveDao.showPage(hql, "select count(1) "+hql, p);
	}

	@Override
	public Page<List<PersonRecord>> searchPersonsOfEquip(String idcard, String eid, String page, String limit) throws Exception {
		String hql = "from PersonRecord where id in (select record.id from EquipmentLeader where receive.match.equipmentdetail.equipmentStorage.id="+eid;
		if(idcard !=null && !idcard.equals("")){
			hql += " and record.idcard='"+idcard+"'";
		}
		hql += ")";
		Page<List<PersonRecord>> p = new Page<List<PersonRecord>>();
		p.setCunrrentPage(Integer.valueOf(page));
		p.setPageSize(Integer.valueOf(limit));
		return receiveDao.showPage(hql, "select count(1) "+hql, p);
	}

	@Override
	public SimStorageDetail searchSimDetail(String rid) throws Exception {
		String hql = "from SimStorageDetail where id = (select match.simdetail.id from Receive where id = "+rid+")";
		List<SimStorageDetail> sims = receiveDao.findByHql(hql);
		if(sims!=null && sims.size()>0){
			return sims.get(0);
		}
		return null;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public int application(EquipmentApc apc) throws Exception {
		//查看申领人 是否存在
		String hql = "from PersonRecord where idcard='"+apc.getPerson().getIdcard()+"'";
		List<PersonRecord> personRecords = receiveDao.findByHql(hql);
		if(personRecords != null && personRecords.size()>0){//申领人已存在
			PersonRecord personRecord = personRecords.get(0);
			if(personRecord.getStatus()!=null && personRecord.getStatus().equals("1")){
				return 3;//档案已停用
			}
			if(personRecord.getHealthCondition()!=null && personRecord.getHealthCondition().getId()==5){
				return 4;//申领人已死亡
			}
		}else{//申领人不存在 添加
			PersonRecord personRecord = new PersonRecord();
			personRecord.setIdcard(apc.getPerson().getIdcard());
			personRecord.setName(apc.getPerson().getName());
			String birth = IdcardUtils.getBirthByIdCard(apc.getPerson().getIdcard());
			personRecord.setBirth(new SimpleDateFormat("yyyyMMdd").parse(birth));
			Agency agency = new Agency();
			agency.setId(new Integer(apc.getAgencyid()));
			personRecord.setAgency(agency);
			personRecord.setCreateTime(new Date());
			User user = new User();
			user.setId(1);
			personRecord.setUser(user);
			if(!receiveDao.add(personRecord)){
				throw new Exception("保存申领人信息失败");
			}
		}

		//记录申领信息
		hql = "from EquipmentKind where id="+apc.getEuipmentid();
		List<EquipmentKind> storages = receiveDao.findByHql(hql);
		EquipmentKind storage = storages.get(0);

		//查看是否已经申领了该类型的相关设备
		String ishas = "from Receive where record.id=(select pr.id from PersonRecord pr where pr.idcard='"+apc.getPerson().getIdcard()+"') and receiveTime=null and " +
				"match.equipmentdetail.equipmentStorage.equipment.kind.id="+storage.getId();
		List rs = receiveDao.findByHql(ishas);
		if(rs!=null && !rs.isEmpty()){
			throw new Exception("用户已经领取了该类型的设备，请退还后在申请");
		}

		MsgContent msgc = new MsgContent();
		msgc.setType(1);
		msgc.setTitle("设备申领");
		msgc.setMsg(apc.getPerson().getName()+"(身份证号："+apc.getPerson().getIdcard()+")申领设备："+storage.getName());
		msgc.setCreateTime(new Date());
		Agency agency = new Agency();
		agency.setId(new Integer(apc.getAgencyid()));
		msgc.setAgency(agency);
		User user = new User();
		user.setId(1);
		msgc.setUser(user);
		if(!receiveDao.add(msgc)){
			throw new Exception("保存申领信息失败");
		}
		return 1;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public ResponseData fault(FaultTreatment faultTreatment) throws Exception {
		if(faultTreatment.getLeaderId()==null || faultTreatment.getLeaderId().equals("")){
			return ResponseData.custom("领用记录主键不能为空");
		}
		if(faultTreatment.getFaultType()==null || faultTreatment.getFaultType().equals("")){
			return ResponseData.custom("故障类型不能为空");
		}
		//查询领用记录
		Receive receive = receiveDao.getById(Receive.class, faultTreatment.getLeaderId());
		if(receive==null){
			return ResponseData.custom("领用记录未找到");
		}
		receive.setStatus(1);
		if(!receiveDao.saveOrUpdateEntity(receive)){
			throw new Exception("更新领用设备状态失败");
		}
		faultTreatment.setCreateTime(new Date());
		faultTreatment.setUpdateTime(new Date());
		if(!receiveDao.add(faultTreatment)){
			throw new Exception("添加故障记录失败");
		}
		return ResponseData.ok();
	}

	@Override
	public ResponseData searchfault(String receiveid) throws Exception {
		String hql = "from FaultTreatment where leaderId="+receiveid +" order by createTime desc";
		List<FaultTreatment> faultTreatments = receiveDao.findByHql(hql);
		if(faultTreatments==null || faultTreatments.isEmpty()){
			return ResponseData.custom("故障记录未找到");
		}
		FaultTreatment faultTreatment = faultTreatments.get(0);
		ResponseData pd = ResponseData.ok();
		pd.putDataValue("faultTreatment",faultTreatment);
		return pd;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public ResponseData editfault(FaultTreatment faultTreatment) throws Exception {
		if(faultTreatment.getId()==null || faultTreatment.getId().equals("")){
			return ResponseData.custom("故障记录主键不能为空");
		}
		FaultTreatment faultTreatment1 = receiveDao.getById(FaultTreatment.class, faultTreatment.getId());
		if(faultTreatment1 == null){
			return ResponseData.custom("故障记录未找到");
		}
		faultTreatment1.setUpdateUserId(faultTreatment.getUpdateUserId());
		faultTreatment1.setUpdateTime(new Date());
		faultTreatment1.setTreatmentMsg(faultTreatment.getTreatmentMsg());
		faultTreatment1.setTreatmentTime(faultTreatment.getTreatmentTime());
		faultTreatment1.setTreatmentStatus(faultTreatment.getTreatmentStatus());
		faultTreatment1.setStatus(faultTreatment.getStatus());
		if(!receiveDao.saveOrUpdateEntity(faultTreatment1)){
			throw new Exception("保存故障处理记录失败");
		}
		if(faultTreatment.getTreatmentStatus()!=null && faultTreatment.getTreatmentStatus() == 2){//设备处理正常
			//查询领用记录
			Receive receive = receiveDao.getById(Receive.class, faultTreatment.getLeaderId());
			if(receive==null){
				return ResponseData.custom("领用记录未找到");
			}
			receive.setStatus(0);
			if(!receiveDao.saveOrUpdateEntity(receive)){
				throw new Exception("更新领用设备状态失败");
			}
		}
		return ResponseData.ok();
	}


	@Override
	@Transactional(rollbackFor=Exception.class)
	public ResponseData addReceive(User user, ReceiveParam receiveParam) throws Exception {
		//参数完整性检查
		if(StringUtils.isEmpty(receiveParam.getSbid())){
			return ResponseData.custom("领用设备未上传");
		}
		List<ReceiverUser> receiverUsers = receiveParam.getRusers();
		ReceiverUser lyr = null;
		if(receiverUsers == null){
			return ResponseData.custom("设备领用人未上传");
		}else{
			for(ReceiverUser receiverUser:receiverUsers){
				if(receiverUser != null){
					if(receiverUser.getLyr()!=null && receiverUser.getLyr()){
						lyr = receiverUser;
					}
				}
			}
			if(lyr == null){
				return ResponseData.custom("设备领用人未选择");
			}
		}

		Receive receive = new Receive();
		receive.setRemark(receiveParam.getRemark());
		receive.setCreateUser(user);
		receive.setCreateTime(new Date());
		ReceiveRecipt receipt = new ReceiveRecipt();
		receipt.setCreateTime(new Date());
		receipt.setReceiptUser(user);
		receipt.setMoney(receiveParam.getEarnestmoney()==null?0:receiveParam.getEarnestmoney());
		Set res = new HashSet<ReceiveRecipt>();
		res.add(receipt);
		receive.setReceipts(res);
		//查看用户是否已经领用过同种设备
		String ishas = "from Receive where record.id="+lyr.getId()+" and receiveTime=null and " +
				"match.equipmentdetail.equipmentStorage.equipment.kind.id=" +
				"(select dm.equipmentStorage.equipment.kind.id from EquipmentStorageDetail dm where dm.id="+receiveParam.getSbid()+")";
		List rs = receiveDao.findByHql(ishas);
		if(rs!=null && !rs.isEmpty()){
			throw new Exception("用户已经领取了该类型的设备，请退还后在申请");
		}
		//如果sim卡信息未上传 查询设备是否已经被领取
		if(StringUtils.isEmpty(receiveParam.getSimid())){
			String ishql = "from DeviceMatch where equipmentdetail.id="+receiveParam.getSbid()+" and noBindTime=null";
			List<DeviceMatch> ms = receiveDao.findByHql(ishql);
			if(ms==null || ms.size()<=0){
				throw new Exception("信息不完整,sim卡信息缺失");
			}else{
				receive.setMatch(ms.get(0));
			}
		}else{
			throw new Exception("信息不完整,设备信息缺失");
		}


		//查看设备、SIM卡是否已被使用
		String issb = "from Receive where (match.equipmentdetail.id="+receiveParam.getSbid();
		if(!StringUtils.isEmpty(receiveParam.getSimid())){
			issb += "or match.simdetail.id="+receiveParam.getSimid()+") ";
		}else{
			issb += ")";
		}
		issb += "and (receiveTime = null or receiveTime = '')";
		List<Object> rec = receiveDao.findByHql(issb);
		if(rec!=null && rec.size()>0){
			throw new Exception("设备或者SIM卡已被使用");
		}

		//保存设备与sim卡信息绑定
		DeviceMatch match = receive.getMatch();
		match.setBindTime(new Date());
		match.setUser(user);

		//查看设备是否已经与SIM卡绑定
		String es = "from DeviceMatch where (equipmentdetail.id="+receiveParam.getSbid();
		if(!StringUtils.isEmpty(receiveParam.getSimid())){
			es += "or simdetail.id="+receiveParam.getSimid()+") ";
		}else{
			es += ")";
		}
		es += " and noBindTime=null";
		List<DeviceMatch> matchs = receiveDao.findByHql(es);
		int idkey = 0;
		if(matchs==null || matchs.size()<=0){//没有绑定
			EquipmentStorageDetail equipmentStorageDetail = new EquipmentStorageDetail();
			equipmentStorageDetail.setId(Integer.valueOf(receiveParam.getSbid()));
			match.setEquipmentdetail(equipmentStorageDetail);
			SimStorageDetail simStorageDetail = new SimStorageDetail();
			simStorageDetail.setId(Integer.valueOf(receiveParam.getSimid()));
			match.setSimdetail(simStorageDetail);
			if((idkey = receiveDao.addNumKey(match))<=0){
				throw new Exception("保存绑定信息失败");
			}
		}else if(matchs.size()==1){//设备与sim卡绑定
			idkey = matchs.get(0).getId();
			match = matchs.get(0);
		}else{
			throw new Exception("设备与SIM卡已经绑定不同的设备");
		}
		match.setId(idkey);
		receive.setMatch(match);
		EquipmentStorageDetail edetail = receiveDao.getById(EquipmentStorageDetail.class, match.getEquipmentdetail().getId());
		receive.setEquipmentName(edetail.getEquipmentName());
		receive.setEmanufacturerName(edetail.getManufacturerName());
		receive.setEsN(edetail.getsN());
		receive.setEspecification(edetail.getEspecification());
		SimStorageDetail sdetail = receiveDao.getById(SimStorageDetail.class, match.getSimdetail().getId());
		receive.setSmanufacturerName(sdetail.getManufacturerName());
		receive.setNetworkName(sdetail.getNerworkName());
		receive.setSsN(sdetail.getsN());
		PersonRecord lyrrecord = new PersonRecord();
		lyrrecord.setId(lyr.getId());
		receive.setRecord(lyrrecord);//设置领用人
		int rid = 0;
		//保存领用记录
		if((rid = receiveDao.addNumKey(receive))>0){
			/**********保存设备-用户绑定记录开始********************/
			List<EquipmentLeader> equipmentLeaders = new ArrayList<>();
			for(ReceiverUser receiverUser:receiverUsers){
				EquipmentLeader leader = new EquipmentLeader();
				//血压计可以设置双用户 其他设备单用户
				if(!StringUtils.isEmpty(receiverUser.getYh())){
					if(receiverUser.getYh().equals("a")){
						leader.setUserNo("1");//设置用户编号1...n
					}else if(edetail.getEquipmentStorage().getEquipment().getKind().getId() == 1){//血压计
						if(receiverUser.getYh().equals("b")){
							leader.setUserNo("2");//设置用户编号1...n
						}
					}else{
						continue;
					}
				}else{
					continue;
				}
				leader.setCreateTime(new Date());
				leader.setCreateUser(user);
				leader.setReceive(receive);
				PersonRecord leaderRecord = new PersonRecord();
				leaderRecord.setId(receiverUser.getId());
				leader.setRecord(leaderRecord);

				equipmentLeaders.add(leader);
			}
			if(equipmentLeaders!=null && !equipmentLeaders.isEmpty()){
				if(!receiveDao.batchSaveOrUpdate(equipmentLeaders)){
					throw new Exception("绑定用户失败");
				}
			}else{
				throw new Exception("没有可绑定的用户");
			}
			/**********保存设备-用户绑定记录结束********************/

			// 更改库存信息状态
			String hql = "update EquipmentStorageDetail set equipmentStatus.id=2 where id="+match.getEquipmentdetail().getId();
			if(!receiveDao.editHql(hql)){
				throw new Exception("更新设备使用状态失败");
			}
			//更新设备库存数
			hql = "update EquipmentStorage set stockNumber = stockNumber-1 where id = ("
					+ "select equipmentStorage.id from EquipmentStorageDetail where id="+match.getEquipmentdetail().getId()+")";
			if(!receiveDao.editHql(hql)){
				throw new Exception("更新设备库存失败");
			}

			String simhql = "update SimStorageDetail set equipmentStatus.id=2 where id="+match.getSimdetail().getId();
			if(!receiveDao.editHql(simhql)){
				throw new Exception("更新SIM卡使用状态失败");
			}
			//更新SIM卡库存数
			simhql = "update SimStorage set stockNumber = stockNumber-1 where id = ("
					+ "select simStorage.id from SimStorageDetail where id="+match.getSimdetail().getId()+")";
			if(!receiveDao.editHql(simhql)){
				throw new Exception("更新SIM卡库存失败");
			}

		}else{
			throw new Exception("保存领用信息失败");
		}
		System.out.println("zhujian:"+rid);
		return ResponseData.ok().putDataValue("rid", rid);
	}
}
